/**
 * Copyright (c) 2017-2024 Nop Platform. All rights reserved.
 * Author: canonical_entropy@163.com
 * Blog:   https://www.zhihu.com/people/canonical-entropy
 * Gitee:  https://gitee.com/canonical-entropy/nop-entropy
 * Github: https://github.com/entropy-cloud/nop-entropy
 */
package com.gitee.wsl.func.select.selector

import com.gitee.wsl.func.select.ISelectionCollector
import com.gitee.wsl.func.select.ISelector
import com.gitee.wsl.func.select.SelectResult

class CompositeSelector<E, C>(
    private val selectors: List<ISelector<E, C, E>>
) : ISelector<E, C, E> {

    override fun toString(): String {
        return selectors.joinToString( "/")
    }

    fun getSelectors(): List<ISelector<E, C, E>> {
        return selectors
    }

    override fun select(element: E, context: C, consumer: ISelectionCollector<E>): SelectResult {
        return runSelect(element, selectors, 0, context, consumer)
    }

    fun runSelect(
        element: E, selectors: List< ISelector<E, C, E>>, index: Int, context: C,
        consumer: ISelectionCollector<E>
    ): SelectResult {
        if (index >= selectors.size) return SelectResult.NOT_FOUND

        val selector: ISelector<E, C, E> = selectors[index]

        val result: SelectResult = selector.select(element, context, { elm: E ->
            // if all selector are matched
            if (index + 1 >= selectors.size) {
                return@select consumer.collect(elm)
            }
            runSelect(elm, selectors, index + 1, context, consumer)
        })

        return result
    }

}